package com.lzy.cacheAnno;

import com.lzy.conf.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 *缓存注解切面
 */
@Component
@Aspect
@Slf4j
public class RedisCacheAspect {
    RedisUtil redisUtil;

    @Value("${jwt.expire}")
    private int expire;

    @Autowired
    public RedisCacheAspect(RedisUtil redisUtil) {
        this.redisUtil = redisUtil;
    }

    @Pointcut("@annotation(com.lzy.cacheAnno.RedisCache)")
    private void RedisCache() {
    }

    @Around("RedisCache()")
    public Object RedisCache(ProceedingJoinPoint pjp) {
        Object rtValue = null;
        try {
            Object[] args = pjp.getArgs();//得到方法执行所需的参数
            MethodSignature signature = (MethodSignature) pjp.getSignature();
            RedisCache annotation = AnnotationUtils.getAnnotation(signature.getMethod(), RedisCache.class);
            String[] value = annotation.value();
            String key = annotation.key();
            String extKey = annotation.extKey();
            String redis_key = key;
            ExpressionParser ep= new SpelExpressionParser();
            EvaluationContext ctx = new StandardEvaluationContext();
            for (int i = 0; i < value.length; i++) {
                ctx.setVariable(value[i], args[i]);
            }
            if(!extKey.equals("")){
                extKey = ep.parseExpression(extKey).getValue(ctx).toString();
                redis_key = key + ":" + extKey;
            }
            Object cach_data = redisUtil.getCacheObject(redis_key);
            if(cach_data != null){
                rtValue = cach_data;
            }else{
                rtValue = pjp.proceed(args);//明确调用切入点方法（切入点方法）
                redisUtil.setCacheObject(redis_key,rtValue,expire, TimeUnit.MINUTES);
            }
            return rtValue;
        } catch (Throwable e) {
            log.error("缓存注解切面异常",e);
            throw new RuntimeException(e);
        } finally {
        }
    }

}
